home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 1 Issue 2 / PDCD-1 - Issue 02.iso / _utilities / utilities / 003 / motorola / Sources / c / as next >
Text File  |  1993-07-18  |  15KB  |  413 lines

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4.  
  5. /* #include <kernel.h> */
  6.  
  7. #include "mselect.h"    /*external selection of microprocessor symbol table*/
  8. #include "proto.h"
  9. #include "as.h"
  10. #include "structs.h"
  11. #include "glovars.h"
  12.  
  13. void            stable(struct nlist * ptr);
  14. void            cross(struct nlist * point);
  15.  
  16. /*
  17.  * as --- cross assembler main program
  18.  * 
  19.  * Note: Compile with define DEBUG for function module debug statements. Compile
  20.  * with define DEBUG2 for version 2 debug statements only.  Compile with
  21.  * define IBM to use original, non- Amiga, non-MAC, non-UNIX fgets()
  22.  * function.  Amiga version will accept IBM generated source code but not the
  23.  * other way around. Note added version (TER) 2.01 19 June 1989.
  24.  */
  25.  
  26. int
  27. main(int argc, char **argv)
  28. {
  29.         char          **np;
  30.         char           *i;
  31.         int             j = 0;
  32.  
  33.         fprintf(stderr, "Assembler release TER_2.0 version 2.09 - (c) Motorola (free ware)\n");
  34.         fprintf(stderr, "Archimedes porting April 1993 Maurizio Ferrari - version 2.00\n");
  35.  
  36.         if (argc < 2) {
  37.                 fprintf(stderr, "Usage:   %s [files] [-options]\n", argv[j]);
  38.                 fprintf(stderr, "Example: %s FILE1.ASM FILE2.ASM -o <Obj_name> -x -list <List_name> -cyc -p50 -crlf -nnf\n", argv[j]);
  39.                 exit(1);
  40.         }
  41.         Argv = argv;
  42.         while ((*argv[j] != '-') && (j < argc)) {
  43. #ifdef DEBUG
  44.                 printf("%s\n", argv[j]);
  45. #endif
  46.                 j++;
  47.         }
  48.         N_files = j - 1;
  49.         Lflag = 0;
  50.         Cflag = 0;
  51.         Sflag = 0;
  52.         CREflag = 0;
  53.         if (j < argc) {
  54.                 while (j < argc) {
  55.                         for (i = argv[j]; *i != 0; i++)
  56.                                 if ((*i <= 'Z') && (*i >= 'A'))
  57.                                         *i = *i + 32;
  58.                         if (strcmp(argv[j], "-list") == 0) {
  59.                                 Lflag = 1;
  60.                         } else if (strcmp(argv[j], "-cyc") == 0)
  61.                                 {Cflag = 1;}
  62.                         else if (strcmp(argv[j], "-sym") == 0)
  63.                                 {Sflag = 1;}
  64.                         else if (strcmp(argv[j], "-x") == 0)
  65.                                 {CREflag = 1;}
  66.                         else if (strcmp(argv[j], "-crlf") == 0) /* test for crlf option */
  67.                                 {CRflag = 1;}     /* add <CR><LF> to S record */
  68.                         /* ver TER_1.1 June 3, 1989 */
  69.                         else if (strcmp(argv[j], "-nnf") == 0)  /* test for nnf option */
  70.                                 {nfFlag = 0;}     /* nfFlag=1 means number
  71.                                                  * INCLUDE separately. ver
  72.                                                  * TER_2.0 6/17/89 */
  73.                         else if (strcmp(argv[j], "-p") == 0)  /* page every 50 lines */
  74.                                 {Pflag50 = 1;
  75.                                 PageLen = atoi(argv[++j]);}    /* ver (TER) 2.01 19 Jun 89 */
  76.                         else if (strcmp(argv[j], "-o") == 0) {
  77.                                 ObjFilePos = ++j;
  78.                         } else if (*argv[j]) {
  79.                                 fprintf(stderr, "\nUnrecognized option '%s' on command line\n", argv[j]);
  80.                                 fprintf(stderr, "Valid options are:");
  81.                                 fprintf(stderr, "  -list  -cyc  -sym  -x  -crlf -nnf -p <pages> -o <Obj name>\n\n");
  82.                                 exit(1);
  83.                         }
  84.                         j++;
  85.                 }
  86.         }
  87.         if (ObjFilePos == 0)
  88.                 fatal("\nmust specify output file");
  89.         /* errorInit(throwback,SourceFileName); */
  90.         fwdinit();              /* forward ref init */
  91.         initialize();
  92.         root = NULL;
  93.         Cfn = 0;
  94.         np = argv;
  95.         Line_num = 0;           /* reset line number */
  96.         Local_Line_num = 0;     /* reset line number */
  97.         while (++Cfn <= N_files)
  98.                 if ((Fd = fopen(*++np, "r")) == NULL) {
  99.                         fprintf(stderr, "as: can't open %s\n", *np);
  100.                 } else {
  101.                         errorInit(1, *np);
  102.                         make_pass();
  103.                         fclose(Fd);
  104.                         errorFinish();
  105.                         Local_Line_num = 0;     /* reset line number */
  106.                 }
  107.         if (Err_count == 0) {
  108.                 Pass++;
  109.                 re_init();
  110.                 Cfn = 0;
  111.                 np = argv;
  112.                 Line_num = 0;
  113.                 Local_Line_num = 0;
  114.                 FdCount = 0;    /* Resets INCLUDE file nesting ver TER_2.0
  115.                                  * 6/17/89 */
  116.                 while (++Cfn <= N_files)
  117.                         if ((Fd = fopen(*++np, "r")) != NULL) {
  118.                                 fprintf(stderr, "\nAssembling %s\n", *np);
  119.                                 errorInit(1, *np);
  120.                                 make_pass();
  121.                                 fclose(Fd);
  122.                                 errorFinish();
  123.                                 Local_Line_num = 0;     /* reset Line_num for
  124.                                                          * throwback */
  125.                         }
  126.                 fprintf(stderr, "\nProgram + Init Data = %d bytes\n", F_total); /* print total bytes */
  127.                 fprintf(stderr, "Error count = %d\n\n", Err_count);     /* rel TER_2.0 */
  128.                 if (Sflag == 1) {
  129.                         fprintf(stderr, "Writing Symbols file\n");
  130.                         stable(root);
  131.                         fclose (Mapfil);
  132.                 }
  133.                 if (CREflag == 1) {
  134.                         fprintf(stderr, "Writing Xref file\n");
  135.                         cross(root);
  136.                         fclose (Xfil);
  137.                 }
  138.                 if (CRflag == 1)
  139.                         fprintf(Objfil, "S9030000FC%c\n", CR);  /* ver TER_1.1 print w
  140.                                                                  * <CR> */
  141.                 else
  142.                         fprintf(Objfil, "S9030000FC\n");        /* at least give a
  143.                                                                  * decent ending */
  144.                 fclose(Objfil); /* close file correctly ver TER_1.1 */
  145.                 fclose(Listfil); /* close file */
  146.         } else {                /* just note errors, TER_2.0 */
  147.                 fprintf(stderr, "\nProgram + Init Data = %d bytes\n", F_total); /* print total bytes */
  148.                 fprintf(stderr, "Error count = %d\n\n", Err_count);
  149.                 fclose(Listfil); /* close file */      
  150.                 }
  151.         fwd_done();
  152.         errorFinish();
  153.         exit(Err_count);        /* neat for UNIX cuz can test return value in
  154.                                  * script but on other systems like Amiga,
  155.                                  * mostly just makes further script
  156.                                  * statements fail if >10, else nothing.
  157.                                  * Therefore, printed out byte count and
  158.                                  * error level. ver (TER) 2.02 19 Jun 89 */
  159. }
  160.  
  161. void
  162. initialize(void)
  163. {
  164.         char            c;
  165.         char            *leafname, *maproot, *xroot, *lroot;/*input file leaf and output names*/
  166.         int             i = 0;
  167.  
  168. #ifdef DEBUG
  169.         printf("Initializing\n");
  170. #endif
  171.         Err_count = 0;
  172.         Pc = 0;
  173.         Pass = 1;
  174.         Ctotal = 0;
  175.         N_page = 0;
  176.         Line[MAXBUF - 1] = NEWLINE;
  177.         if (strlen(Argv[ObjFilePos]) > FILENAME_MAX)
  178.                 fatal("obj_file name too long ");
  179.         Obj_name = (char *) malloc(strlen(Argv[ObjFilePos]));
  180.         lroot = (char *) malloc(strlen(Argv[1]));
  181.         maproot = (char *) malloc(strlen(Argv[1]));
  182.         xroot = (char *) malloc(strlen(Argv[1]));
  183.         if (Obj_name == NULL)
  184.                 fatal("Cannot allocate space for obj name");
  185.         if (lroot == NULL)
  186.                 fatal("Cannot allocate space for list file name");
  187.         if (maproot == NULL)
  188.                 fatal("Cannot allocate space for  map file name");
  189.         if (xroot == NULL)
  190.                 fatal("Cannot allocate space for xref file name");
  191. #ifdef DEBUG
  192.         printf("%d, %d\n", strlen(Argv[ObjFilePos]), sizeof(char));
  193.         printf("Oun =%s-\n", Obj_name);
  194.  
  195. #endif
  196.         do {                    /* copy -o <file name> into Obj_name */
  197.                 c = Obj_name[i] = Argv[ObjFilePos][i];
  198.                 i++;
  199.         } while (c && (i < FILENAME_MAX));
  200.  
  201. #ifdef DEBUG
  202.         printf("Fwd =%s\n", Fwd_name);
  203.         printf("Obj =%s\n", Obj_name);
  204. #endif
  205.         Obj_name[--i] = EOS;
  206.         printf ("S19 Obj file:  %s\n", Obj_name);
  207.         if ((Objfil = fopen(Obj_name, "w")) == NULL) {
  208.                 fatal("Can't create object file");
  209.         }
  210.  
  211.         leafname = strrchr (Argv[1], '.');
  212.         if (leafname == NULL)  
  213.                 {fatal ("cannot decipher leafname: empty ?");}
  214.  
  215.         i=strlen(Argv[1]);
  216.         do {
  217.                 i--;
  218.         } while (Argv[1][i-1] != '.');
  219.         do {
  220.                 i--;
  221.         } while (Argv[1][i-1] != '.');
  222. if (Lflag)
  223. {        strncpy(lroot, Argv[1], i-1);
  224.         lroot[i-1] = EOS;
  225.         lroot=strcat(lroot, ".l");
  226.         lroot=strcat(lroot, leafname);
  227.         printf ("Listing file: %s\n", lroot);
  228.         if ((Listfil = fopen(lroot, "w")) == NULL) {
  229.                 fatal("Panic! Can't create listing file");
  230.         }
  231. }
  232. if (Sflag)
  233. {       strncpy(maproot, Argv[1], i-1);
  234.         maproot[i-1] = EOS;
  235.         maproot=strcat(maproot, ".m");
  236.         maproot=strcat(maproot, leafname);
  237. printf ("Symbols file: %s\n", maproot);
  238.         if ((Mapfil = fopen(maproot, "w")) == NULL) {
  239.                 fatal("Panic! Can't create symbols map file. Does 'm' dir exist?");
  240.         }
  241. }
  242. if (CREflag)
  243. {        strncpy(xroot, Argv[1], i-1);
  244.         xroot[i-1] = EOS;
  245.         xroot=strcat(xroot, ".x");
  246.         xroot=strcat(xroot, leafname);
  247. printf ("Xref file   : %s\n", xroot);
  248.         if ((Xfil = fopen(xroot, "w")) == NULL) {
  249.                 fatal("Panic! Can't create xref file. Does 'x' dir exist?");
  250.         }
  251. }
  252.  
  253.         localinit();            /* target machine specific init. */
  254. }
  255.  
  256. void
  257. re_init(void)
  258. {
  259. #ifdef DEBUG
  260.         printf("Reinitializing\n");
  261. #endif
  262.         Pc = 0;
  263.         E_total = 0;
  264.         P_total = 0;
  265.         Ctotal = 0;
  266.         N_page = 0;
  267.         fwdreinit();
  268. }
  269.  
  270. void
  271. make_pass(void)
  272. {
  273.         /*
  274.          * #ifdef IBM char *fgets();
  275.          *//* the original line */
  276.         /* #else */
  277.         /* char *FGETS(); *//* use own FGETS which is rewrite of lib function */
  278.         /* such that it discards <CR> so can read code */
  279.         /* generated on IBM */
  280.         /* June 3, 1989 rev TER_1.1 */
  281.         /* #endif */
  282.  
  283. #ifdef DEBUG
  284.         printf("Pass %d\n", Pass);
  285. #endif
  286.         while (FGETS(Line, MAXBUF - 1, Fd) != (char *) NULL) {  /* changed to FGETS */
  287.                 /* which does not pass on <CR>  June 3, 1989 */
  288.                 /* rev TER_1.1 */
  289.                 Line_num++;
  290.                 Local_Line_num++;
  291.                 P_force = 0;    /* No force unless bytes emitted */
  292.                 N_page = 0;
  293.                 if (parse_line())
  294.                         process();
  295.                 if (Pass == 2 && Lflag && !N_page)
  296.                         print_line();
  297.                 P_total = 0;    /* reset byte count */
  298.                 Cycles = 0;     /* and per instruction cycle count */
  299.         }
  300.         f_record();
  301. }
  302.  
  303.  
  304. /*
  305.  * parse_line --- split input line into label, op and operand
  306.  */
  307. int
  308. parse_line(void)
  309. {
  310.         register char  *ptrfrm = Line;
  311.         register char  *ptrto = Label;
  312.         /* char *skip_white(); */
  313.  
  314.         if (*ptrfrm == '*' || *ptrfrm == '\n' || *ptrfrm == ';')
  315.                 /* added check for ';' ver TER_1.1 */
  316.                 /* June 3, 1989 */
  317.                 return (0);     /* a comment line */
  318.  
  319.         while (delim(*ptrfrm) == NO)    /* parsing Label */
  320.                 *ptrto++ = *ptrfrm++;
  321.         if (*--ptrto != ':')
  322.                 ptrto++;        /* allow trailing : */
  323.         *ptrto = EOS;
  324.  
  325.         ptrfrm = skip_white(ptrfrm);
  326.         if (*ptrfrm == ';') {   /* intercept comment after label, ver TER_2.0 */
  327.                 *Op = *Operand = EOS;   /* comment, no Opcode or Operand */
  328.                 return (1);
  329.         }
  330.         ptrto = Op;
  331.  
  332.         while (delim(*ptrfrm) == NO)    /* parsing Opcode */
  333.                 *ptrto++ = mapdn(*ptrfrm++);
  334.         *ptrto = EOS;
  335.  
  336.         ptrfrm = skip_white(ptrfrm);
  337.         if (*ptrfrm == ';') {   /* intercept comment, ver TER_2.0 */
  338.                 *Operand = EOS; /* comment, no Operand */
  339.                 return (1);
  340.         }
  341.         ptrto = Operand;
  342.         while ((*ptrfrm != NEWLINE) && ((*ptrfrm != ';')||(*Op != 'fcc')))        /* ver TER_2.0 */
  343.                 *ptrto++ = *ptrfrm++;   /* kill comments */         /* buggy: if FCC ';'
  344.                                                                      * error reported
  345.                                                                      * removed 27/6/93 */ 
  346.         *ptrto = EOS;
  347.  
  348. #ifdef DEBUG
  349.         printf("Label-%s-\n", Label);
  350.         printf("Op----%s-\n", Op);
  351.         printf("Operand-%s-\n", Operand);
  352. #endif
  353.         return (1);
  354. }
  355.  
  356. /*
  357.  * process --- determine mnemonic class and act on it
  358.  */
  359. void
  360. process(void)
  361. {
  362.         register struct oper *i;
  363.         /* struct oper *mne_look(); */
  364.  
  365.         Old_pc = Pc;            /* setup `old' program counter */
  366.         Optr = Operand;         /* point to beginning of operand field */
  367.  
  368.         if (*Op == EOS) {       /* no mnemonic */
  369.                 if (*Label != EOS)
  370.                         install(Label, Pc);
  371.         } else if ((i = mne_look(Op)) == NULL)
  372.                 error("Unrecognized Mnemonic");
  373.         else if (i->class == PSEUDO)
  374.                 do_pseudo(i->opcode);
  375.         else {
  376.                 if (*Label)
  377.                         install(Label, Pc);
  378.                 if (Cflag)
  379.                         Cycles = i->cycles;
  380.                 do_op(i->opcode, i->class);
  381.                 if (Cflag)
  382.                         Ctotal += Cycles;
  383.         }
  384. }
  385.  
  386. #ifndef IBM
  387. char           *
  388. FGETS(char *s, int n, register FILE * iop)
  389. {                               /* get at most n chars from iop */
  390.         /* Added rev TER_1.1 June 3, 1989 */
  391.         /* Adapted from Kernighan & Ritchie */
  392.         /*
  393.          * An fgets() that is IBM proof. Not needed if this IS an IBM
  394.          */
  395.         register int    c;
  396.         register char  *cs;
  397.  
  398.         cs = s;
  399.         while (--n > 0 && (c = getc(iop)) != EOF) {     /* read chars if not
  400.                                                          * file end */
  401.                 if ((*cs = c) != CR)
  402.                         cs++;   /* incr buffer pointer if not CR */
  403.                 /* If CR, leave to be written over */
  404.                 if (c == '\n')
  405.                         break;
  406.         }
  407.         *cs = '\0';             /* replace NEWLINE with NULL as in standard
  408.                                  * fgets() */
  409.         return ((c == EOF && cs == s) ? NULL : s);      /* return NULL if this
  410.                                                          * is EOF */
  411. }
  412. #endif
  413.